Fix retrying crate downloads for network errors
authorAlex Crichton <alex@alexcrichton.com>
Wed, 30 Nov 2016 00:52:20 +0000 (16:52 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Thu, 1 Dec 2016 04:43:19 +0000 (20:43 -0800)
Previously the `with_retry` loop was a little too tight where stale state about
the sha256 and data was kept out of the loop. Instead we need to reinitialize
these on each iteration of the loop to ensure that we correctly retry by
forgetting the data we previously downloaded for an aborted download attempt.

src/cargo/sources/registry/remote.rs

index 480b7185950a626b56c57bed44cf116af79a1b0d..2b9b1ca02dd6f6f07985281c5c04aee528eeb95d 100644 (file)
@@ -158,17 +158,17 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> {
         handle.follow_location(true)?;
         let mut state = Sha256::new();
         let mut body = Vec::new();
-        {
+        network::with_retry(self.config, || {
+            state = Sha256::new();
+            body = Vec::new();
             let mut handle = handle.transfer();
             handle.write_function(|buf| {
                 state.update(buf);
                 body.extend_from_slice(buf);
                 Ok(buf.len())
             })?;
-            network::with_retry(self.config, || {
-                handle.perform()
-            })?
-        }
+            handle.perform()
+        })?;
         let code = handle.response_code()?;
         if code != 200 && code != 0 {
             bail!("failed to get 200 response from `{}`, got {}", url, code)